﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using eShop.Model;
using eShop.DataAccess;
using eShop.Business;
using System.Text;
using eShop.Utility;
using Entity;

namespace eShop.Business
{
    public class ProductManager
    {
        #region _ACTIVE_FUNCTION

        public static void CreateProduct(Product product, List<ProductImage> additionalImages)
        {
            if (ProductDAO.CountItemNumber(product.ItemNumber) > 0)
                throw new Exception(ApplicationMessage.DuplicateProductItemNumber);

            Category category = CategoryManager.GetCategoryById(product.CategoryId);
            if (category.SubCategoryCount > 0)
                throw new InvalidOperationException(ApplicationMessage.InvalidCategoryForProductAddition);

            if (!String.IsNullOrEmpty(product.ProductImageUrl))
            {
                product.ProductImageUrl = PrpareProductImage(product.ProductImageUrl);
            }

            product.ProductUrl = CreateProductUrl(product.ProductId, product.ProductName, category.CategoryUrl);
            ProductDAO.Save(product);
            
            product.ProductUrl = CreateProductUrl(product.ProductId, product.ProductName, category.CategoryUrl);
            ProductDAO.Save(product);

            foreach (ProductStock productStock in product.Stocks)
            {
                productStock.ProductId = product.ProductId;
                ProductStockManager.Create(productStock);
            }
            
            CreateAdditionalProductImage(product.ProductId, additionalImages);
        }

        public static void UpdateProduct(Product product, List<ProductImage> additionalImages)
        {
            Product oldProduct = GetProductById(product.ProductId);
            Category category = CategoryManager.GetCategoryById(product.CategoryId);

            if (string.Compare(oldProduct.ProductName, product.ProductName, true) != 0)
            {
                product.ProductUrl = CreateProductUrl(product.ProductId, product.ProductName, category.CategoryUrl);
            }
            if (oldProduct.CategoryId != product.CategoryId)
            {
                if (category.SubCategoryCount > 0)
                    throw new InvalidOperationException(ApplicationMessage.InvalidCategoryForProductAddition);
            }
            if (!String.IsNullOrEmpty(product.ProductImageUrl)
                && string.Compare(oldProduct.ProductImageUrl, product.ProductImageUrl, true) != 0)
            {
                product.ProductImageUrl = PrpareProductImage(product.ProductImageUrl);
                FileAccessUtility.DeleteFile(product.ProductImageUrl);
            }

            ProductDAO.Save(product);

            foreach (ProductStock productStock in product.Stocks)
            {
                productStock.ProductId = product.ProductId;
                ProductStockManager.Update(productStock);
            }

            CreateAdditionalProductImage(product.ProductId, additionalImages);
        }

        /****************************************/

        private static string CreateProductUrl(int productId, string productName, string categoryUrl)
        {
            string productUrl = categoryUrl + SiteUtility.CleanProductName(productName) + "-" + productId + ".aspx";
            return productUrl.ToLower();
        }

        private static void CreateAdditionalProductImage(int ProductId, List<ProductImage> productImages)
        {
            foreach (ProductImage productImage in productImages)
            {
                CreateAdditionalProductImage(ProductId, productImage);
            }
        }

        private static void CreateAdditionalProductImage(int ProductId, ProductImage productImage)
        {
            if (!String.IsNullOrEmpty(productImage.AdditionalImageUrl))
            {
                productImage.AdditionalImageUrl = PrpareProductImage(productImage.AdditionalImageUrl);
            }
            productImage.ProductID = ProductId;
            ProductImageDAO.Save(productImage);
        }

        private static string PrpareProductImage(string temporaryProductImage)
        {
            string destinationFileName = Guid.NewGuid().ToString();
            string originalImageFilePath = WebPresentationUtility.CopyImageAndResize(temporaryProductImage,
                    ApplicationSettings.ProductImagePath, destinationFileName, "_original", 0);

            WebPresentationUtility.CopyImageAndResize(temporaryProductImage, ApplicationSettings.ProductImagePath,
                destinationFileName, "_smallthumb", 90);
            WebPresentationUtility.CopyImageAndResize(temporaryProductImage, ApplicationSettings.ProductImagePath,
                destinationFileName, "_largethumb", 250);
            WebPresentationUtility.CopyImageAndResize(temporaryProductImage, ApplicationSettings.ProductImagePath,
                destinationFileName, "_detail", 388);

            FileAccessUtility.DeleteFile(temporaryProductImage);
            return originalImageFilePath;
        }

        #endregion


        /****************************************/
        /****************************************/
        /****************************************/


        #region _INACTIVE_FUNCTION

        public static List<Product> Search(string keyword, string itemNumber,
            SearchType searchType)
        {
            if (searchType == SearchType.SearchByItemNumberAndKeyword)
            {
                if (string.IsNullOrEmpty(keyword))
                    keyword = "%";
                if (string.IsNullOrEmpty(itemNumber))
                    itemNumber = "%";

                return ProductDAO.GetProductByKeywordAndItemNumber(keyword, itemNumber);
            }
            else
                return null;
        }

        public static List<Product> SearchByBothName(int currentPageIndex, int pageSize, string keyword, string itemNumber, SearchType searchType)
        {
            if (searchType == SearchType.SearchByItemNumberAndKeyword)
            {
                if (string.IsNullOrEmpty(keyword))
                    keyword = "%";
                if (string.IsNullOrEmpty(itemNumber))
                    itemNumber = "%";

                return ProductDAO.GetProductByBothName((currentPageIndex - 1) * pageSize, pageSize, keyword, itemNumber);
            }
            else
                return null;
        }

        public static int SearchByBothNameCount(string keyword, string itemNumber, SearchType searchType)
        {
            if (searchType == SearchType.SearchByItemNumberAndKeyword)
            {
                if (string.IsNullOrEmpty(keyword))
                    keyword = "%";
                if (string.IsNullOrEmpty(itemNumber))
                    itemNumber = "%";

                return ProductDAO.GetProductByBothNameCount(keyword, itemNumber);
            }
            else
                return 0;
        }

        public static List<Product> FeaturedProducts(int howMany)
        {
            List<Product> featuredProduct = new List<Product>();
            try
            {
                return ProductDAO.GetFeaturedProducts(howMany);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        
        public static List<Product> GetAllTblPartnerProductByPartnerName(string partnerName, string categoryName)
        {
            List<Product> featuredProduct = new List<Product>();
            try
            {
                return PartnerProductDAO.GetAllTblPartnerProductByPartnerName(partnerName, categoryName);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static List<Product> ProductByManufacturer(int brandId, int currentPageIndex, int pageSize, DataState dataState)
        {
            List<Product> productData = null;

            if (dataState == DataState.Active)
            {
                productData = ProductDAO.GetActiveProductsByBrand(brandId, (currentPageIndex - 1) * pageSize, pageSize);
            }
            else if (dataState == DataState.NonDeleted)
            {
                productData = ProductDAO.GetNonDeletedProductsByBrand(brandId, (currentPageIndex - 1) * pageSize, pageSize);
            }
            else if (dataState == DataState.All)
            {
                productData = ProductDAO.GetAllProductsByBrand(brandId, (currentPageIndex - 1) * pageSize, pageSize);
            }
            return productData;
        }

        public static List<Product> ProductByCategory(int categoryId, string orderby, int currentPageIndex, int pageSize, DataState dataState)
        {
            List<Product> productData = null;

            if (dataState == DataState.Active)
            {
                productData = ProductDAO.GetActiveProductsByCategory(orderby, categoryId, (currentPageIndex - 1) * pageSize, pageSize);
            }
            else if (dataState == DataState.NonDeleted)
            {
                productData = ProductDAO.GetNonDeletedProductsByCategory(categoryId, (currentPageIndex - 1) * pageSize, pageSize);
            }
            else if (dataState == DataState.All)
            {
                productData = ProductDAO.GetAllProductsByCategory(categoryId, (currentPageIndex - 1) * pageSize, pageSize);
            }
            return productData;
        }

        public static List<Product> Products(int currentPageIndex, int pageSize, DataState dataState)
        {
            List<Product> productData = null;

            if (dataState == DataState.Active)
            {
                productData = ProductDAO.GetActiveProducts((currentPageIndex - 1) * pageSize, pageSize);
            }
            else if (dataState == DataState.NonDeleted)
            {
                productData = ProductDAO.GetNonDeletedProducts((currentPageIndex - 1) * pageSize, pageSize);
            }
            else if (dataState == DataState.All)
            {
                productData = ProductDAO.GetAllTblProductPaged("ProductName", (currentPageIndex - 1) * pageSize, pageSize);
            }
            return productData;
        }
        public static List<Product> SpecialProducts(int currentPageIndex, int pageSize, DataState dataState)
        {
            List<Product> productData = null;

            if (dataState == DataState.Active)
            {
                productData = ProductDAO.GetActiveSpecialProducts((currentPageIndex - 1) * pageSize, pageSize);
            }
            else if (dataState == DataState.NonDeleted)
            {
                productData = ProductDAO.GetNonDeletedProducts((currentPageIndex - 1) * pageSize, pageSize);
            }
            else if (dataState == DataState.All)
            {
                productData = ProductDAO.GetAllTblProductPaged("ProductName", (currentPageIndex - 1) * pageSize, pageSize);
            }
            return productData;
        }

        public static int ProductCountByCategory(int categoryId, DataState dataState)
        {
            int count = 0;

            if (dataState == DataState.Active)
            {
                count = ProductDAO.GetActiveProductsCountByCategory(categoryId);
            }
            else if (dataState == DataState.NonDeleted)
            {
                count = ProductDAO.GetNonDeletedProductsCountByCategory(categoryId);
            }
            else if (dataState == DataState.All)
            {
                count = ProductDAO.GetAllProductsCountByCategory(categoryId);
            }
            return count;
        }

        public static int ProductCountByManufacturer(int brandId, DataState dataState)
        {
            int count = 0;

            if (dataState == DataState.Active)
            {
                count = ProductDAO.GetActiveProductsCountByBrand(brandId);
            }
            else if (dataState == DataState.NonDeleted)
            {
                count = ProductDAO.GetNonDeletedProductsCountByBrand(brandId);
            }
            else if (dataState == DataState.All)
            {
                count = ProductDAO.GetAllProductsCountByBrand(brandId);
            }
            return count;
        }

        public static int ProductCount(DataState dataState)
        {
            int count = 0;

            if (dataState == DataState.Active)
            {
                count = ProductDAO.GetActiveProductsCount();
            }
            else if (dataState == DataState.NonDeleted)
            {
                count = ProductDAO.GetNonDeletedProductsCount();
            }
            else if (dataState == DataState.All)
            {
                count = ProductDAO.GetAllTblProductPagedCount("", 0, 0);
            }
            return count;
        }

        public static Product Load(string prodPath)
        {
            try
            {
                prodPath = "~/" + prodPath;
                Product productData = ProductDAO.GetTblProductByProductPath(prodPath);
                Manufacturer brandData = null;
                Category categoryData = null;

                if (productData != null && productData.BrandId > 0)
                    brandData = ManufacturerManager.GetManufacturerById(productData.BrandId);
                if (productData != null)
                    categoryData = CategoryManager.GetCategoryById(productData.CategoryId);

                if (brandData != null)
                    productData.Brand = brandData;
                if (categoryData != null)
                    productData.Category = categoryData;

                List<ProductStock> productStockData = ProductStockDAO.GetProductStockByProductId(productData.ProductId);
                productData.Stocks = productStockData;
                return productData;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public static Product Load(int productId, string supplierName)
        {
            try
            {
                Product productData = PartnerProductDAO.GetTblPartnerProductByPartnerName(supplierName, productId);
                Manufacturer brandData = null;
                Category categoryData = null;

                if (productData != null)
                {
                    //brandData = TblProductBrand.(productData.p);
                    brandData = ManufacturerDAO.GetTblProductBrandByProductBrandUrl(supplierName);
                }
                if (productData != null)
                    categoryData = CategoryManager.GetCategoryById(productData.CategoryId);

                if (brandData != null)
                    productData.Brand = brandData;
                if (categoryData != null)
                    productData.Category = categoryData;

                List<ProductStock> productStockData = ProductStockDAO.GetProductStockByProductId(productData.ProductId);
                productData.Stocks = productStockData;
                return productData;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public static Product GetProductById(int productId)
        {
            Product productData = ProductDAO.GetTblProductByProductId(productId);
            Manufacturer brandData = null;
            Category categoryData = null;

            if (productData != null && productData.BrandId > 0)
                brandData = ManufacturerManager.GetManufacturerById(productData.BrandId);
            if (productData != null)
            {
                categoryData = CategoryManager.GetCategoryById(productData.CategoryId);
                
            }

            if (brandData != null)
                productData.Brand = brandData;
            if (categoryData != null)
                productData.Category = categoryData;
            List<ProductStock> stocks = ProductStockManager.GetStockByProductId(productId);
            if (stocks != null && stocks.Count > 0)
            {
                productData.Stocks = stocks;
            }
            productData.AdditionalImages = ProductImageDAO.GetTblProductAdditionalImageByProductID(productId);
            return productData;
        }

        public static int GetBackEndProductListBySearchCount(string productName, int categoryId, bool includeDeleted)
        {
            int count = ProductDAO.GetBackEndProductListCount(productName, categoryId, includeDeleted);

            return count;
        }
        public static int GetBackEndProductListBySearchCountAdmin(string productName, string itemNumber, int categoryId, bool includeDeleted)
        {
            int count = ProductDAO.GetBackEndProductListCountAdmin(productName, itemNumber, categoryId, includeDeleted);

            return count;
        }

        public static List<Product> GetBackEndProductListBySearch(string productName, int categoryId,
            bool includeDeleted, string sortBy, int firstItem, int pageSize)
        {
            return ProductDAO.GetBackEndProductList(productName, categoryId, includeDeleted, sortBy, firstItem, pageSize);
        }

        public static List<Product> GetBackEndProductListBySearchAdmin(string productName, string itemNumber, int categoryId,
          bool includeDeleted, string sortBy, int firstItem, int pageSize)
        {
            return ProductDAO.GetBackEndProductListAdmin(productName, itemNumber, categoryId, includeDeleted, sortBy, firstItem, pageSize);
        }

        public static void DeleteProducts(List<int> idList)
        {
            ProductDAO.DeleteTblProductList(idList);
        }

        public static List<Product> GetBackendProductPurchaseProductListBySoldDate(DateTime fromdate, DateTime todate)
        {
            return ProductDAO.GetBackendProductPurchaseProductListBySoldDate(fromdate, todate);
        }

        public static List<Product> GetProductByCategoryURL(string catName)
        {
            List<Product> productData = null;
            if (catName != null)
                productData = ProductDAO.GetProductByCategoryURL(catName);

            return productData;
        }

        public static void ReduceStock(int stockId, int qty)
        {
            ProductStock productStock = ProductStockManager.GetStockById(stockId);
            if (productStock != null)
            {
                productStock.StockAvailable = productStock.StockAvailable - qty;
                ProductStockManager.Update(productStock);
            }
        }

        public static bool SavePartner(ManufacturerProduct productPartner)
        {
            return PartnerProductDAO.Save(productPartner);
        }

        public static bool DeletePartnerProductList(List<Decimal> partnerProductIdListToDelete)
        {
            return PartnerProductDAO.DeleteTblPartnerProductList(partnerProductIdListToDelete);
        }

        public static ManufacturerProduct GetPartnerProductById(Decimal partnerProductId)
        {
            return PartnerProductDAO.GetTblPartnerProductByPartnerProductId(partnerProductId);
        }

        public static List<ManufacturerProduct> GetPartnerProductByProductId(Int32 prodId)
        {
            return PartnerProductDAO.GetAllTblPartnerProductByProductId(prodId);
        }

        public static bool SaveProductImage(ProductImage productImage)
        {
            return ProductImageDAO.Save(productImage);
        }

        public static ProductImage GetProductAdditionalImageById(int id)
        {
            return ProductImageDAO.GetTblProductAdditionalImageByID(id);
        }

        public static bool DeleteAdditionalImage(int imageId)
        {
            return ProductImageDAO.DeleteTblProductAdditionalImage(imageId);
        }

        public static List<ProductImage> GetProductAdditionalImagesByProductId(int productId)
        {
            return ProductImageDAO.GetTblProductAdditionalImageByProductID(productId);
        }

        public static List<ProductReview> GetProductReviewByProduct(int productId)
        {
            return ProductReviewDAO.GetTblProductReviewByProductId(productId);
        }

        public static int CreateNewProductReview(ProductReview productReview)
        {
            return ProductReviewDAO.CreateNewTblProductReview(productReview);
        }

        public static List<ProductReview> GetAllProductReviewsWithProductPaged(string orderBy, int startRowIndex, int maximumRows)
        {
            return ProductReviewDAO.GetAllProductReviewsWithProductPaged(orderBy, startRowIndex, maximumRows); ;
        }

        public static int GetAllProductReviewsWithProductPagedCount()
        {
            return ProductReviewDAO.GetAllProductReviewsWithProductPagedCount();
        }

        public static ProductReview GetTblProductReviewByProductReviewId(Int32 productReviewId)
        {
            return ProductReviewDAO.GetTblProductReviewByProductReviewId(productReviewId);
        }

        public static bool SaveProductReview(ProductReview productReview)
        {
            return ProductReviewDAO.Save(productReview);
        }

        public static bool DeleteTblProductReviewList(List<int> ids)
        {
            return ProductReviewDAO.DeleteTblProductReviewList(ids);
        }

        #endregion
    }
}